package repository

import (
	"context"
	cache2 "jk-time/webook/internal/cache"
	"jk-time/webook/internal/domain"
)

//go:generate mockgen -source=./ranking.go -package=mocks -destination=mocks/ranking.mock.go RankingRepository
type RankingRepository interface {
	SetTopN(ctx context.Context, arts []domain.PublishedArticle) error
	GetTopN(ctx context.Context) ([]domain.PublishedArticle, error)
	SetTopNAndComment(ctx context.Context, arts []domain.PublishedArticleComment) error
	GetTopNAndComment(ctx context.Context) ([]domain.PublishedArticleComment, error)
}

type CachedRankingRepository struct {
	redisCache cache2.RankingCache
	localCache cache2.Cache
}

func NewCachedRankingRepository(redisCache cache2.RankingCache, localCache cache2.Cache) RankingRepository {
	return &CachedRankingRepository{redisCache: redisCache, localCache: localCache}
}

func (c *CachedRankingRepository) SetTopN(ctx context.Context, arts []domain.PublishedArticle) error {
	_ = c.localCache.Set(ctx, arts)
	return c.redisCache.SetTopN(ctx, arts)
}

func (c *CachedRankingRepository) GetTopN(ctx context.Context) ([]domain.PublishedArticle, error) {
	arts, err := c.localCache.Get(ctx)
	if err == nil {
		return arts, err
	}
	arts, err = c.redisCache.GetTopN(ctx)
	if err == nil {
		_ = c.localCache.Set(ctx, arts)
		return arts, err
	} else {
		// 再绕回来
		return c.localCache.ForceGet(ctx)
	}
}
func (c *CachedRankingRepository) SetTopNAndComment(ctx context.Context, arts []domain.PublishedArticleComment) error {
	return c.redisCache.SetTopNAndComment(ctx, arts)
}
func (c *CachedRankingRepository) GetTopNAndComment(ctx context.Context) ([]domain.PublishedArticleComment, error) {
	return c.redisCache.GetTopNAndComment(ctx)
}
